/******************************************************************************
 * Copyright 2017-2018 Baidu Robotic Vision Authors. All Rights Reserved.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 *****************************************************************************/

#ifndef XP_INCLUDE_XP_WORKER_ACTUATOR_IMPL_H_
#define XP_INCLUDE_XP_WORKER_ACTUATOR_IMPL_H_

#include <XP/worker/actuator.h>
#include <string>
#include <mutex>

namespace XP {

  // This actuator controls a EAI base
class EaiActuator : public Actuator {
 public:
  EaiActuator() {}
  ~EaiActuator() {}
  bool init() override;
  bool stopActProcess() override;
  bool control(const XP_TRACKER::GuideMessage& guide_message);
};

// This actuator controls a Kinco base
class DililiActuator : public Actuator {
 public:
  DililiActuator(const std::string& dev, const float diameter);
  ~DililiActuator();
  bool init() override;
  bool stopActProcess() override;
  bool control(const XP_TRACKER::GuideMessage& guide_message) override;
  bool getUltrasoundObstacle() override;

 public:
  // Dilili desk specific functions
  bool deskUp();
  bool deskDown();
  bool deskStop();
  bool deskResetAlarm();
  bool lightSwitch(int gry, bool on_off);

  bool resetAndEnableWheels();
  bool powerOnSeparateWheels();   // before moving
  bool powerOffSeparateWheels();  // so you can push the desk
  bool resetAndEnableSeparateWheelControl();
  bool allowForcedMoving(bool allow_forced_moving);
  bool sendKincoCommand(uint32_t cmd, int32_t data, int id = 0x01,  // wheel 2 is 0x02
                        uint32_t* res = nullptr);
  bool setWheelRps_lr(int rps_l, int rps_r);

  // Device related
  std::string dev_str_;
  int fd_;
  uint8_t ultrasound_flag_;  // Each bit indicates an ultrasound_sensor. e.g. 0x1 is A 0x3 is AB
  float diameter_;  // Distance between two wheels
  bool allow_forced_moving_;  // Whether or not the Dilili desk can be forced moving around.
  std::mutex serial_port_mutex_;  // Protect the serial port accessing in multithread
};

}  // namespace XP
#endif  //  XP_INCLUDE_XP_WORKER_ACTUATOR_IMPL_H_
